package com.vpx.server.service.system.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.CaseFormat;
import com.vpx.server.bean.entity.*;
import com.vpx.server.bean.order.base.BaseDelOrder;
import com.vpx.server.bean.order.base.BaseIdStrOrder;
import com.vpx.server.bean.order.system.*;
import com.vpx.server.bean.result.system.*;
import com.vpx.server.framework.base.ResultMsg;
import com.vpx.server.framework.utils.DateUtils;
import com.vpx.server.mapper.system.*;
import com.vpx.server.service.system.*;
import com.vpx.server.utils.UserLoginUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author PC
 * @Date 2023/11/18 16:31
 **/
@Service
public class TemplateServiceImpl extends ServiceImpl<TemplateMapper, Template> implements TemplateService {
    @Resource
    private TempalteAttrMapper tempalteAttrMapper;
    @Autowired
    private TemplateAttrService templateAttrService;
    @Resource
    private CTypeMapper typeMapper;
    @Resource
    private CTypeRelMapper typeRelMapper;

    @Resource
    private BaseInfoAttrMapper baseInfoAttrMapper;

    @Resource
    private SqlExtService sqlExtService;

    @Resource
    SqlService sqlService;


    @Override
    public ResultMsg saveTemplate(TemplateOrder order) {
        Template entity = new Template();
        BeanUtil.copyProperties(order,entity);
        entity.setCreateUser(UserLoginUtils.getCurrentUser() == null ? "admin" : UserLoginUtils.getCurrentUser().getId().toString());
        entity.setCreateTime(DateUtils.getDateTimeStr());
        baseMapper.insert(entity);
        return ResultMsg.success(entity.getId());
    }

    @Override
    public ResultMsg deleteTemplate(BaseDelOrder order) {
        baseMapper.deleteById(order.getId());
        //删除关联表
        sqlExtService.execute("delete from c_type_rel where transaction_id = '"+order.getId()+"'");
        //删除模板属性
        sqlExtService.execute("delete from c_template_attr where template_id = '"+order.getId()+"'");
        return ResultMsg.success();
    }

    @Override
    public ResultMsg updateTemplateById(TemplateOrder order) {
        if (StrUtil.isEmpty(order.getId())){
            return ResultMsg.fail("数据id不能为空");
        }
        Template template = baseMapper.selectById(order.getId());
        if (template == null){
            return ResultMsg.fail("数据不存在，请刷新重试");
        }
        BeanUtil.copyProperties(order,template);
        updateById(template);
        return ResultMsg.success(template.getId());
    }

    @Override
    public ResultMsg<TemplateResult> selectTemplateById(BaseIdStrOrder order) {
        if (StrUtil.isEmpty(order.getId())){
            return ResultMsg.fail("数据id不能为空");
        }
        Template template = baseMapper.selectById(order.getId());
        if (template == null){
            return ResultMsg.fail("数据不存在，请刷新重试");
        }
        TemplateResult result = new TemplateResult();
        BeanUtil.copyProperties(template,result);
        return ResultMsg.success(result);
    }

    @Override
    public ResultMsg<TemplatePageResult> pageQueryTemplate(TemplatePageOrder order) {
        PageHelper.startPage(order.getPageNum(), order.getPageSize());
        QueryWrapper<Template> wrapper = new QueryWrapper();
        wrapper.like(StrUtil.isNotBlank(order.getTemplateName()),"template_name",order.getTemplateName());
        wrapper.like(StrUtil.isNotBlank(order.getTemplateCode()),"template_code",order.getTemplateCode());
        wrapper.eq(StrUtil.isNotBlank(order.getTemplateType()),"template_type",order.getTemplateType());
        wrapper.eq(StrUtil.isNotBlank(order.getTypeId()),"type_id",order.getTypeId());

        wrapper.orderByDesc("create_time");
        List<Template> templates = this.list(wrapper);

        PageInfo<Template> pageInfo = new PageInfo<>(templates);
        PageInfo<TemplateResult> pageInfo2 = new PageInfo<>();
        BeanUtil.copyProperties(pageInfo,pageInfo2);
        if (CollUtil.isNotEmpty(templates)){
            List<TemplateResult> resultList = new ArrayList<>();
            Set<String> typeIds = new HashSet<>();
            List<String> tranList = this.sqlExtService.findList("select template_id from c_template_tran group by template_id", String.class);
            templates.forEach(e -> {
                TemplateResult result =  new TemplateResult();
                BeanUtil.copyProperties(e,result);
                if(tranList.contains(result.getId())) {
                    result.setTransStatus("1");
                } else {
                    result.setTransStatus("0");
                }
                resultList.add(result);
            });
            pageInfo2.setList(resultList);

        }
        if (CollUtil.isEmpty(templates)){
            List<TemplateResult> resultList = new ArrayList<>();
            Set<String> typeIds = new HashSet<>();
            templates.forEach(e -> {
                TemplateResult result =  new TemplateResult();
                BeanUtil.copyProperties(e,result);
                resultList.add(result);
                typeIds.add(e.getTypeId());
            });

            pageInfo2.setList(resultList);
            //查询类别
            List<CType> cTypes = null;
            if(CollUtil.isNotEmpty(typeIds)) {
                cTypes = typeMapper.selectBatchIds(typeIds);
            }

            if (CollUtil.isNotEmpty(cTypes)){
                Map<String,String> typeNameMap = cTypes.stream().collect(Collectors.toMap(e -> e.getId(),e -> e.getTypeName()));
                resultList.forEach(te -> {
                    String typeName = typeNameMap.get(te.getTypeId());
                    if (StrUtil.isNotBlank(typeName)){
                        te.setTypeName(typeName);

                    }

                });
            }
        }

        TemplatePageResult result = new TemplatePageResult();
        result.setPageInfo(pageInfo2);
        return ResultMsg.success(result);
    }

    @Override
    public ResultMsg<TemplateDetailListResult> templateDetailAttrList(String templateId) {
        Template template = baseMapper.selectById(templateId);
        if (template == null){
            return ResultMsg.fail("模板不存在");
        }
        TemplateDetailListResult result = new TemplateDetailListResult();
        BeanUtil.copyProperties(template,result);
        //查询类别
        CType cType = typeMapper.selectById(template.getTypeId());
        if (cType != null){
            result.setTypeName(cType.getTypeName());
        }

        //查询属性
        QueryWrapper<TemplateAttr> attrQueryWrapper = new QueryWrapper<>();
        attrQueryWrapper.eq("template_id",template.getId()).orderByDesc("create_time");
        List<TemplateAttr> templateAttrs = tempalteAttrMapper.selectList(attrQueryWrapper);
        if (CollUtil.isEmpty(templateAttrs)){
            return ResultMsg.success(result);
        }
        List<TemplateAttrResult> attrResultList = new ArrayList<>();
        templateAttrs.forEach(attr -> {
            TemplateAttrResult attrResult = new TemplateAttrResult();
            BeanUtil.copyProperties(attr,attrResult);
            attrResultList.add(attrResult);
        });
        result.setAttrResultList(attrResultList);
        return ResultMsg.success(result);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultMsg templateAttrSaveUpdate(TemplateOrder order) {
        //保存属性
        List<TemplateAttrOrder> attrOrders = order.getAttrOrders();
        Map<String,String> codeMap = new HashMap<>();
        //判断属性编码是否重复
        if(attrOrders != null) {
            boolean flag = false;
            for(TemplateAttrOrder attrOrder: attrOrders) {
                if(codeMap.get(attrOrder.getAttrCode()) != null) {
                    flag = true;
                    break;
                } else {
                    codeMap.put(attrOrder.getAttrCode(),attrOrder.getAttrCode());
                }
            }
            if(flag) {
                ResultMsg.fail("属性编码重复!");
            }
        }
        String templateId;
        String code = "2";
        //1、硬件配置 2、总线配置 3、协议配置 4、共享配置 5、观察者配置 6、流程步 7、测试用例 8、流程项 9 自动判读 10 激励信号 11 条件流程 12 界面操作 13 通用流程
        //(1、测试用例 2、工具分类（测试步） 3、激励型号 4、自动判读  5、条件 6 界面操作 7 通用)
        if("6".equals(order.getTemplateType())) {
            code = "2";
        } else if("7".equals(order.getTemplateType())) {
            code = "1";
        } else if("10".equals(order.getTemplateType())) {
            code = "3";
        } else if("9".equals(order.getTemplateType())) {
            code = "4";
        } else if("11".equals(order.getTemplateType())) {
            code = "5";
        } else if("12".equals(order.getTemplateType())) {
            code = "6";
        } else if("13".equals(order.getTemplateType())) {
            code = "7";
        }
        boolean updateFlag = true;//判断是否是修改
        if (StrUtil.isEmpty(order.getId())){
            //新增
            templateId = saveTemplate(order).getData().toString();
            //保存类别与模板关联信息
            CTypeRel typeRel = new CTypeRel();
            typeRel.setTypeId(order.getTypeId());
            typeRel.setTransactionId(templateId);
            typeRel.setCode(code);
            typeRel.setCreateTime(DateUtils.getDateTimeStr());
            typeRel.setId(IdUtil.simpleUUID());
            typeRelMapper.add(typeRel);
            updateFlag = false;
        }else {
            //修改
            templateId = updateTemplateById(order).getData().toString();

            //保存类别与模板关联信息
            CTypeRel typeRel = new CTypeRel();
            typeRel.setTypeId(order.getTypeId());
            QueryWrapper<CTypeRel> typeRelQueryWrapper = new QueryWrapper<>();
            typeRelQueryWrapper.eq("transaction_id",templateId);
            typeRelQueryWrapper.eq("code",code);
            typeRelMapper.update(typeRel,typeRelQueryWrapper);
        }



        if (CollUtil.isNotEmpty(attrOrders)){
            attrOrders.forEach(e -> {
                e.setTemplateId(templateId);
            });
        }

        templateAttrService.batchSaveUpdate(attrOrders,templateId, updateFlag);
        return ResultMsg.success();
    }


    @Override
    public ResultMsg<List<JSONObject>> nodeTemplateDetailAttrList(String nodeId) {


        List<JSONObject> templateAttrs = this.sqlExtService.findListObject("select * from c_base_info_attr where base_info_id = '"+nodeId+"' order by sort_num asc", JSONObject.class);
        List<JSONObject> attrResultList = new ArrayList<>();
        if (CollUtil.isEmpty(templateAttrs)){
            return ResultMsg.success(attrResultList);
        }
        templateAttrs.forEach(attr -> {
            JSONObject obj = JSONUtil.createObj();
            Set<String> keys = attr.keySet();
            Iterator<String> iterator = keys.iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                obj.putByPath(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, key), attr.get(key));
            }
            attrResultList.add(obj);
        });
        return ResultMsg.success(attrResultList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultMsg baseInfoAttrSaveUpdate(BaseInfoAttrListOrder order) {
        Map<String,String> codeMap = new HashMap<>();
        //判断属性编码是否重复
        if(order.getBaseInfoAttrs() != null) {
            boolean flag = false;
            for(BaseInfoAttrOrder attrOrder: order.getBaseInfoAttrs()) {
                if(codeMap.get(attrOrder.getAttrCode()) != null) {
                    flag = true;
                    break;
                } else {
                    codeMap.put(attrOrder.getAttrCode(),attrOrder.getAttrCode());
                }
            }
            if(flag) {
                ResultMsg.fail("属性编码重复!");
            }
        }
        //查出当前节点的所有属性ID
        List<String> oldAttrIds = this.sqlExtService.findList("select id from c_base_info_attr where base_info_id = '"+order.getBaseInfoId()+"'", String.class);
        List<String> newAttrIds = new ArrayList<>();
        List<BaseInfoAttrOrder> baseInfoAttrs = order.getBaseInfoAttrs();
        if(baseInfoAttrs != null) {
            baseInfoAttrs.forEach(baseInfoAttr -> {
                if(StringUtils.isNotBlank(baseInfoAttr.getId())) {
                    newAttrIds.add(baseInfoAttr.getId());
                } else {
                    baseInfoAttr.setId(IdUtil.getSnowflakeNextIdStr());
                    baseInfoAttr.setCreateTime(DateUtils.getDateTimeStr());
                    baseInfoAttr.setCreateUser(UserLoginUtils.getCurrentUser() == null ? "admin" : UserLoginUtils.getCurrentUser().getId().toString());
                    baseInfoAttr.setBaseInfoId(order.getBaseInfoId());
                }
            });
        }


        if(oldAttrIds != null) {
            List<String> delIds = (List<String>)CollUtil.subtract(oldAttrIds, newAttrIds);
            if(delIds.size() > 0) {
                //删除移除的ID
                String idStr = "'" + StrUtil.join("','",delIds) + "'";
                this.sqlExtService.execute("delete from c_base_info_attr where id in ("+idStr+")");
            }
        }
        Map<String, Object> param = new HashMap<>();
        param.put("list", baseInfoAttrs);
        this.sqlService.execute("11", param);

        return ResultMsg.success();
    }
}
